{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center>\n",
    "    <p style=\"text-align:center\">\n",
    "        <img alt=\"phoenix logo\" src=\"https://storage.googleapis.com/arize-phoenix-assets/assets/phoenix-logo-light.svg\" width=\"200\"/>\n",
    "        <br>\n",
    "        <a href=\"https://docs.arize.com/phoenix/\">Docs</a>\n",
    "        |\n",
    "        <a href=\"https://github.com/Arize-ai/phoenix\">GitHub</a>\n",
    "        |\n",
    "        <a href=\"https://join.slack.com/t/arize-ai/shared_invite/zt-1px8dcmlf-fmThhDFD_V_48oU7ALan4Q\">Community</a>\n",
    "    </p>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook demonstrates how to use the Financial Advisor agent with **full observability through Phoenix tracing**. The agent provides comprehensive financial advice through a team of specialized AI sub-agents:\n",
    "\n",
    "1. **Data Analyst Agent**: Creates market analysis reports for specific stock tickers\n",
    "2. **Trading Analyst Agent**: Develops trading strategies based on risk tolerance and investment duration\n",
    "3. **Execution Agent**: Creates implementation plans for trading strategies\n",
    "4. **Risk Evaluation Agent**: Analyzes risks and provides mitigation strategies\n",
    "\n",
    "**🔍 Phoenix Tracing**: All agent interactions, tool usage, and LLM calls are automatically traced and sent to Phoenix for observability, performance monitoring, and evaluation.\n",
    "\n",
    "**⚠️ Important Disclaimer**: This is for educational purposes only and does not constitute financial advice.\n",
    "\n",
    "✅ You will need a Google Cloud account with Vertex AI enabled and an optional Phoenix Cloud account to run this notebook.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Set Up Keys & Dependencies\n",
    "\n",
    "## Install Dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install \"google-cloud-aiplatform[adk,agent-engines]>=1.93.0\" \"google-genai>=1.9.0\" \"pydantic>=2.10.6\" \"python-dotenv>=1.0.1\" \"google-adk>=1.0.0\" \"openinference-instrumentation-google-adk\" \"arize-phoenix-otel\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Google Cloud Setup\n",
    "\n",
    "The Financial Advisor agent requires Google Cloud setup because it uses:\n",
    "- **Vertex AI** for Gemini 2.5 Pro model\n",
    "- **Google Search** tools for market data analysis\n",
    "\n",
    "1. **Create a Google Cloud Project** (if you don't have one)\n",
    "2. **Enable required APIs:**\n",
    "   - Vertex AI API\n",
    "   - Generative AI API\n",
    "\n",
    "3. **Set up authentication:**\n",
    "   ```bash\n",
    "   gcloud auth application-default login\n",
    "   gcloud auth application-default set-quota-project YOUR-PROJECT-ID\n",
    "   ```\n",
    "\n",
    "## Environment Variables\n",
    "\n",
    "Create a `.env` file in this directory with the following variables:\n",
    "\n",
    "```bash\n",
    "# Required for Google ADK\n",
    "GOOGLE_GENAI_USE_VERTEXAI=1\n",
    "GOOGLE_CLOUD_PROJECT=your-project-id\n",
    "GOOGLE_CLOUD_LOCATION=your-project-location  # e.g., us-central1\n",
    "\n",
    "# Optional: Phoenix Cloud Configuration (for production use)\n",
    "# PHOENIX_API_KEY=your-phoenix-api-key\n",
    "# PHOENIX_COLLECTOR_ENDPOINT=your-phoenix-hostname\n",
    "```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "load_dotenv()\n",
    "\n",
    "# Google Cloud authentication - required for the ADK agent\n",
    "if not (google_cloud_project := os.getenv(\"GOOGLE_CLOUD_PROJECT\")):\n",
    "    google_cloud_project = getpass(\"🔑 Enter your Google Cloud Project ID: \")\n",
    "os.environ[\"GOOGLE_CLOUD_PROJECT\"] = google_cloud_project\n",
    "\n",
    "if not (google_cloud_location := os.getenv(\"GOOGLE_CLOUD_LOCATION\")):\n",
    "    google_cloud_location = getpass(\"🔑 Enter your Google Cloud Location (e.g., us-central1): \")\n",
    "os.environ[\"GOOGLE_CLOUD_LOCATION\"] = google_cloud_location\n",
    "\n",
    "# Set required environment variable for Vertex AI\n",
    "os.environ[\"GOOGLE_GENAI_USE_VERTEXAI\"] = \"true\"\n",
    "\n",
    "# Optional: Phoenix Cloud Configuration\n",
    "# If not set, traces will be sent to a local Phoenix instance\n",
    "if phoenix_api_key := os.getenv(\"PHOENIX_API_KEY\"):\n",
    "    print(\"✅ Phoenix API key found - traces will be sent to Phoenix Cloud\")\n",
    "    if phoenix_endpoint := os.getenv(\"PHOENIX_COLLECTOR_ENDPOINT\"):\n",
    "        print(f\"✅ Using Phoenix endpoint: {phoenix_endpoint}\")\n",
    "else:\n",
    "    print(\"📍 No Phoenix API key found - traces will be sent to local Phoenix instance\")\n",
    "    print(\n",
    "        \"💡 To use Phoenix Cloud, set PHOENIX_API_KEY and PHOENIX_COLLECTOR_ENDPOINT environment variables\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Configure Tracing\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from google.adk.agents import LlmAgent\n",
    "from google.adk.tools import google_search\n",
    "from google.adk.tools.agent_tool import AgentTool\n",
    "\n",
    "from phoenix.otel import register\n",
    "\n",
    "# Configure the Phoenix tracer\n",
    "tracer_provider = register(\n",
    "    project_name=\"google-adk-financial-advisor\",  # Project name for organizing traces\n",
    "    auto_instrument=True,  # Auto-instrument your app based on installed OI dependencies\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Build Financial Advisor System\n",
    "\n",
    "Here we define all the prompts and agents inline to make this notebook completely standalone."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the main coordinator prompt\n",
    "FINANCIAL_COORDINATOR_PROMPT = \"\"\"\n",
    "Role: Act as a specialized financial advisory assistant.\n",
    "Your primary goal is to guide users through a structured process to receive financial advice by orchestrating a series of expert subagents.\n",
    "You will help them analyze a market ticker, develop trading strategies, define execution plans, and evaluate the overall risk.\n",
    "\n",
    "Overall Instructions for Interaction:\n",
    "\n",
    "At the beginning, Introduce yourself to the user first. Say something like: \"\n",
    "\n",
    "Hello! I'm here to help you navigate the world of financial decision-making.\n",
    "My main goal is to provide you with comprehensive financial advice by guiding you through a step-by-step process.\n",
    "We'll work together to analyze market tickers, develop effective trading strategies, define clear execution plans,\n",
    "and thoroughly evaluate your overall risk.\n",
    "\n",
    "Remember that at each step you can always ask to \"show me the detailed result as markdown\".\n",
    "\n",
    "Ready to get started?\n",
    "\"\n",
    "\n",
    "Then show immediately this Disclaimer:\n",
    "\n",
    "\"Important Disclaimer: For Educational and Informational Purposes Only.\n",
    "The information and trading strategy outlines provided by this tool, including any analysis,\n",
    "commentary, or potential scenarios, are generated by an AI model and are for educational and informational purposes only.\n",
    "They do not constitute, and should not be interpreted as, financial advice, investment recommendations, endorsements,\n",
    "or offers to buy or sell any securities or other financial instruments.\n",
    "Google and its affiliates make no representations or warranties of any kind, express or implied, about the completeness,\n",
    "accuracy, reliability, suitability, or availability with respect to the information provided. Any reliance you place\n",
    "on such information is therefore strictly at your own risk.\n",
    "This is not an offer to buy or sell any security.\n",
    "Investment decisions should not be made based solely on the information provided here.\n",
    "Financial markets are subject to risks, and past performance is not indicative of future results.\n",
    "You should conduct your own thorough research and consult with a qualified independent financial advisor before making any investment decisions.\n",
    "By using this tool and reviewing these strategies, you acknowledge that you understand this disclaimer and agree that\n",
    "Google and its affiliates are not liable for any losses or damages arising from your use of or reliance on this information.\"\n",
    "\n",
    "At each step, clearly inform the user about the current subagent being called and the specific information required from them.\n",
    "After each subagent completes its task, explain the output provided and how it contributes to the overall financial advisory process.\n",
    "Ensure all state keys are correctly used to pass information between subagents.\n",
    "Here's the step-by-step breakdown.\n",
    "For each step, explicitly call the designated subagent and adhere strictly to the specified input and output formats:\n",
    "\n",
    "* Gather Market Data Analysis (Subagent: data_analyst_agent)\n",
    "* Develop Trading Strategies (Subagent: trading_analyst_agent)\n",
    "* Define Optimal Execution Strategy (Subagent: execution_analyst_agent)\n",
    "* Evaluate Overall Risk Profile (Subagent: risk_analyst_agent)\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Data Analyst Agent Prompt\n",
    "DATA_ANALYST_PROMPT = \"\"\"\n",
    "Agent Role: data_analyst\n",
    "Tool Usage: Exclusively use the Google Search tool.\n",
    "\n",
    "Overall Goal: To generate a comprehensive and timely market analysis report for a provided_ticker. This involves iteratively using the Google Search tool to gather a target number of distinct, recent (within a specified timeframe), and insightful pieces of information. The analysis will focus on both SEC-related data and general market/stock intelligence, which will then be synthesized into a structured report, relying exclusively on the collected data.\n",
    "\n",
    "Inputs (from calling agent/environment):\n",
    "- provided_ticker: (string, mandatory) The stock market ticker symbol (e.g., AAPL, GOOGL, MSFT). The data_analyst agent must not prompt the user for this input.\n",
    "- max_data_age_days: (integer, optional, default: 7) The maximum age in days for information to be considered \"fresh\" and relevant.\n",
    "- target_results_count: (integer, optional, default: 10) The desired number of distinct, high-quality search results to underpin the analysis.\n",
    "\n",
    "Expected Final Output (Structured Report):\n",
    "The data_analyst must return a single, comprehensive report with the following structure:\n",
    "\n",
    "**Market Analysis Report for: [provided_ticker]**\n",
    "**Report Date:** [Current Date of Report Generation]\n",
    "**Information Freshness Target:** Data primarily from the last [max_data_age_days] days.\n",
    "**Number of Unique Primary Sources Consulted:** [Actual count]\n",
    "\n",
    "**1. Executive Summary:**\n",
    "   * Brief (3-5 bullet points) overview of the most critical findings and overall outlook based *only* on the collected data.\n",
    "\n",
    "**2. Recent SEC Filings & Regulatory Information:**\n",
    "   * Summary of key information from recent SEC filings.\n",
    "   * If no significant recent SEC filings were found, explicitly state this.\n",
    "\n",
    "**3. Recent News, Stock Performance Context & Market Sentiment:**\n",
    "   * **Significant News:** Summary of major news items impacting the company/stock.\n",
    "   * **Stock Performance Context:** Brief notes on recent stock price trends.\n",
    "   * **Market Sentiment:** Predominant sentiment with brief justification.\n",
    "\n",
    "**4. Recent Analyst Commentary & Outlook:**\n",
    "   * Summary of recent analyst ratings, price target changes, and key rationales.\n",
    "   * If no significant recent analyst commentary was found, explicitly state this.\n",
    "\n",
    "**5. Key Risks & Opportunities (Derived from collected data):**\n",
    "   * **Identified Risks:** Bullet-point list of critical risk factors.\n",
    "   * **Identified Opportunities:** Bullet-point list of potential opportunities.\n",
    "\n",
    "**6. Key Reference Articles:**\n",
    "   * List of sources with titles, URLs, publication dates, and brief relevance notes.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Trading Analyst Agent Prompt\n",
    "TRADING_ANALYST_PROMPT = \"\"\"\n",
    "Develop Tailored Trading Strategies (Subagent: trading_analyst)\n",
    "\n",
    "Overall Goal for trading_analyst:\n",
    "To conceptualize and outline at least five distinct trading strategies by critically evaluating the comprehensive market_data_analysis_output.\n",
    "Each strategy must be specifically tailored to align with the user's stated risk attitude and their intended investment period.\n",
    "\n",
    "Inputs (to trading_analyst):\n",
    "- User Risk Attitude (user_risk_attitude): Conservative, Moderate, or Aggressive\n",
    "- User Investment Period (user_investment_period): Short-term, Medium-term, or Long-term\n",
    "- Market Analysis Data (from state): market_data_analysis_output\n",
    "\n",
    "Expected Output:\n",
    "Generate at least 5 distinct trading strategies, each containing:\n",
    "1. Strategy Name and Description\n",
    "2. Rationale based on market analysis\n",
    "3. Alignment with user's risk profile and timeline\n",
    "4. Key indicators to monitor\n",
    "5. Entry and exit conditions\n",
    "6. Specific risks for this strategy\n",
    "\n",
    "Format the output as a detailed markdown report with clear sections for each strategy.\n",
    "\n",
    "Important Disclaimer: Include the standard financial disclaimer that this is for educational purposes only and not financial advice.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Execution Analyst Agent Prompt\n",
    "EXECUTION_ANALYST_PROMPT = \"\"\"\n",
    "Define Optimal Execution Strategy (Subagent: execution_analyst)\n",
    "\n",
    "Overall Goal:\n",
    "To create a comprehensive and actionable execution plan for implementing the proposed trading strategies. This plan must be precisely tailored to the user's risk tolerance, investment timeframe, and execution preferences.\n",
    "\n",
    "Inputs:\n",
    "- proposed_trading_strategies_output (from state): The trading strategies developed by the trading analyst\n",
    "- user_risk_attitude: The user's risk tolerance level\n",
    "- user_investment_period: The user's investment timeframe\n",
    "- user_execution_preferences (optional): Any specific broker, order type, or execution preferences\n",
    "\n",
    "Expected Output:\n",
    "Generate a detailed execution plan covering:\n",
    "\n",
    "**I. Foundational Execution Philosophy**\n",
    "- Goal alignment with user profile\n",
    "- Risk management approach\n",
    "- Cost control priorities\n",
    "\n",
    "**II. Entry Execution Strategy**\n",
    "- Optimal entry conditions and timing\n",
    "- Recommended order types and placement\n",
    "- Initial position sizing and risk allocation\n",
    "- Initial stop-loss strategy\n",
    "\n",
    "**III. Holding & In-Trade Management Strategy**\n",
    "- Active monitoring vs. passive holding approach\n",
    "- Dynamic risk management (stop-loss adjustments)\n",
    "- Handling volatility and drawdowns\n",
    "\n",
    "**IV. Accumulation (Scaling-In) Strategy**\n",
    "- Conditions and rationale for adding to positions\n",
    "- Execution tactics for scaling in\n",
    "- Risk adjustment for larger positions\n",
    "\n",
    "**V. Partial Sell (Profit-Taking) Strategy**\n",
    "- Triggers and rationale for partial exits\n",
    "- Execution tactics for scaling out\n",
    "- Managing remaining positions\n",
    "\n",
    "**VI. Full Exit Strategy**\n",
    "- Conditions for complete position exit\n",
    "- Order types and execution approach\n",
    "- Slippage and market impact considerations\n",
    "\n",
    "Format as a detailed markdown report with clear sections for each strategy type.\n",
    "\n",
    "Important: Include the standard financial disclaimer.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Risk Analyst Agent Prompt\n",
    "RISK_ANALYST_PROMPT = \"\"\"\n",
    "Evaluate Overall Risk Profile (Subagent: risk_analyst)\n",
    "\n",
    "Overall Goal:\n",
    "To provide a comprehensive risk analysis of the proposed financial plan, evaluating the consistency between market analysis, trading strategies, execution plan, and the user's stated risk tolerance and investment horizon.\n",
    "\n",
    "Inputs:\n",
    "- market_data_analysis_output (from state): The market analysis data\n",
    "- proposed_trading_strategies_output (from state): The proposed trading strategies\n",
    "- execution_plan_output (from state): The execution plan\n",
    "- user_risk_attitude: The user's stated risk tolerance\n",
    "- user_investment_period: The user's stated investment timeframe\n",
    "\n",
    "Expected Output:\n",
    "Generate a comprehensive risk assessment report covering:\n",
    "\n",
    "**1. Executive Summary of Risks**\n",
    "- Primary risk factors identified\n",
    "- Overall qualitative risk assessment\n",
    "- Alignment with user's risk profile\n",
    "\n",
    "**2. Market Risks**\n",
    "- Identified market-related risks\n",
    "- Assessment of potential impact\n",
    "- Mitigation strategies\n",
    "\n",
    "**3. Liquidity Risks**\n",
    "- Assessment of liquidity concerns\n",
    "- Mitigation approaches\n",
    "\n",
    "**4. Counterparty & Platform Risks**\n",
    "- Broker and platform-related risks\n",
    "- Recommended safeguards\n",
    "\n",
    "**5. Operational & Technological Risks**\n",
    "- Execution and operational risks\n",
    "- Human error factors\n",
    "- Technology-related concerns\n",
    "\n",
    "**6. Strategy-Specific & Model Risks**\n",
    "- Risks specific to chosen strategies\n",
    "- Model and assumption risks\n",
    "- Concentration risks\n",
    "\n",
    "**7. Psychological Risks for the Trader**\n",
    "- Behavioral and emotional risks\n",
    "- Discipline and adherence challenges\n",
    "\n",
    "**8. Overall Alignment with User Profile & Concluding Remarks**\n",
    "- Assessment of alignment with user's stated preferences\n",
    "- Potential misalignments or concerns\n",
    "- Critical considerations and recommendations\n",
    "\n",
    "Format as a detailed markdown report with clear risk categories and actionable recommendations.\n",
    "\n",
    "Important: Include the comprehensive financial disclaimer.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the Sub-Agents\n",
    "MODEL = \"gemini-2.5-pro\"\n",
    "\n",
    "# Data Analyst Agent\n",
    "data_analyst_agent = LlmAgent(\n",
    "    model=MODEL,\n",
    "    name=\"data_analyst_agent\",\n",
    "    description=\"Analyzes market data and creates comprehensive market reports using Google Search\",\n",
    "    instruction=DATA_ANALYST_PROMPT,\n",
    "    output_key=\"market_data_analysis_output\",\n",
    "    tools=[google_search],\n",
    ")\n",
    "\n",
    "# Trading Analyst Agent\n",
    "trading_analyst_agent = LlmAgent(\n",
    "    model=MODEL,\n",
    "    name=\"trading_analyst_agent\",\n",
    "    description=\"Develops customized trading strategies based on market analysis and user preferences\",\n",
    "    instruction=TRADING_ANALYST_PROMPT,\n",
    "    output_key=\"proposed_trading_strategies_output\",\n",
    ")\n",
    "\n",
    "# Execution Analyst Agent\n",
    "execution_analyst_agent = LlmAgent(\n",
    "    model=MODEL,\n",
    "    name=\"execution_analyst_agent\",\n",
    "    description=\"Creates detailed execution plans for implementing trading strategies\",\n",
    "    instruction=EXECUTION_ANALYST_PROMPT,\n",
    "    output_key=\"execution_plan_output\",\n",
    ")\n",
    "\n",
    "# Risk Analyst Agent\n",
    "risk_analyst_agent = LlmAgent(\n",
    "    model=MODEL,\n",
    "    name=\"risk_analyst_agent\",\n",
    "    description=\"Provides comprehensive risk analysis and evaluation of financial plans\",\n",
    "    instruction=RISK_ANALYST_PROMPT,\n",
    "    output_key=\"final_risk_assessment_output\",\n",
    ")\n",
    "\n",
    "print(\"✓ All sub-agents created successfully!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the Main Financial Coordinator Agent\n",
    "financial_coordinator = LlmAgent(\n",
    "    name=\"financial_coordinator\",\n",
    "    model=MODEL,\n",
    "    description=(\n",
    "        \"guide users through a structured process to receive financial \"\n",
    "        \"advice by orchestrating a series of expert subagents. help them \"\n",
    "        \"analyze a market ticker, develop trading strategies, define \"\n",
    "        \"execution plans, and evaluate the overall risk.\"\n",
    "    ),\n",
    "    instruction=FINANCIAL_COORDINATOR_PROMPT,\n",
    "    output_key=\"financial_coordinator_output\",\n",
    "    tools=[\n",
    "        AgentTool(agent=data_analyst_agent),\n",
    "        AgentTool(agent=trading_analyst_agent),\n",
    "        AgentTool(agent=execution_analyst_agent),\n",
    "        AgentTool(agent=risk_analyst_agent),\n",
    "    ],\n",
    ")\n",
    "\n",
    "print(\"✓ Financial Coordinator Agent created successfully!\")\n",
    "print(f\"Agent Name: {financial_coordinator.name}\")\n",
    "print(f\"Model: {financial_coordinator.model}\")\n",
    "print(f\"Number of sub-agents: {len(financial_coordinator.tools)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Test the Financial Advisor Agent\n",
    "\n",
    "The following helper functions allow you to interact with the financial advisor agent from within a Jupyter notebook. They handle agent initialization, session management, and provide async wrappers for querying the agent and displaying responses.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from google.adk.runners import InMemoryRunner\n",
    "from google.genai.types import Part, UserContent\n",
    "\n",
    "# Initialize the runner and session once\n",
    "runner = None\n",
    "session = None\n",
    "\n",
    "\n",
    "async def initialize_runner():\n",
    "    \"\"\"Initialize the runner and session for the agent.\"\"\"\n",
    "    global runner, session\n",
    "    if runner is None:\n",
    "        runner = InMemoryRunner(agent=financial_coordinator)\n",
    "        session = await runner.session_service.create_session(\n",
    "            app_name=runner.app_name, user_id=\"demo_user\"\n",
    "        )\n",
    "    return runner, session\n",
    "\n",
    "\n",
    "async def run_agent_query_async(query: str):\n",
    "    \"\"\"Async helper function to run a query against the financial advisor agent.\"\"\"\n",
    "    try:\n",
    "        runner, session = await initialize_runner()\n",
    "        content = UserContent(parts=[Part(text=query)])\n",
    "\n",
    "        response_parts = []\n",
    "\n",
    "        # Better handling of async iteration with proper error handling\n",
    "        async_iterator = runner.run_async(\n",
    "            user_id=session.user_id,\n",
    "            session_id=session.id,\n",
    "            new_message=content,\n",
    "        )\n",
    "\n",
    "        try:\n",
    "            async for event in async_iterator:\n",
    "                # More defensive checks for event content\n",
    "                if event and hasattr(event, \"content\") and event.content:\n",
    "                    if hasattr(event.content, \"parts\") and event.content.parts:\n",
    "                        if (\n",
    "                            len(event.content.parts) > 0\n",
    "                            and event.content.parts[0]\n",
    "                            and hasattr(event.content.parts[0], \"text\")\n",
    "                            and event.content.parts[0].text\n",
    "                        ):\n",
    "                            response_parts.append(event.content.parts[0].text)\n",
    "        except GeneratorExit:\n",
    "            # Handle generator exit gracefully (common with OpenTelemetry context issues)\n",
    "            pass\n",
    "        except Exception as iter_error:\n",
    "            print(f\"Warning: Error during iteration: {iter_error}\")\n",
    "            # Continue with whatever we collected so far\n",
    "\n",
    "        result = \"\".join(response_parts) if response_parts else \"No response generated\"\n",
    "        return result\n",
    "\n",
    "    except Exception as e:\n",
    "        import traceback\n",
    "\n",
    "        print(f\"Error in run_agent_query_async: {str(e)}\")\n",
    "        traceback.print_exc()\n",
    "        return f\"Error: {str(e)}\"\n",
    "\n",
    "\n",
    "# Simple wrapper to use in Jupyter - just call with await\n",
    "async def query_agent(query: str):\n",
    "    \"\"\"Simple function to query the agent - use with 'await query_agent(your_question)'\"\"\"\n",
    "    response = await run_agent_query_async(query)\n",
    "    return response\n",
    "\n",
    "\n",
    "def print_response(title: str, response: str, max_length: int = None):\n",
    "    \"\"\"Helper function to print formatted responses.\"\"\"\n",
    "    print(f\"\\n{'=' * 60}\")\n",
    "    print(f\"{title}\")\n",
    "    print(f\"{'=' * 60}\")\n",
    "\n",
    "    if max_length and len(response) > max_length:\n",
    "        print(response[:max_length] + \"\\n\\n... [Response truncated for display]\")\n",
    "    else:\n",
    "        print(response)\n",
    "    print(f\"{'=' * 60}\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 📊 Phoenix Tracing Dashboard\n",
    "\n",
    "Once you start running the examples below, you can view the traces in Phoenix:\n",
    "\n",
    "**Local Phoenix Instance:**\n",
    "- Visit: http://localhost:6006\n",
    "- View traces in real-time as agents execute\n",
    "- Analyze performance metrics and token usage\n",
    "\n",
    "**Phoenix Cloud:**\n",
    "- Visit your Phoenix Cloud dashboard\n",
    "- Access advanced analytics and collaboration features\n",
    "\n",
    "**What You'll See in Phoenix:**\n",
    "- 🔗 **Trace Trees**: Complete execution flows from user query to final response\n",
    "- ⏱️ **Timing Data**: Latency for each agent and tool call  \n",
    "- 💰 **Token Usage**: Input/output tokens and cost tracking\n",
    "- 🔍 **Tool Calls**: Detailed logs of Google Search and agent interactions\n",
    "- 📊 **Performance Metrics**: Aggregate statistics across all runs\n",
    "\n",
    "The traces provide invaluable insights for debugging, optimization, and understanding how your multi-agent system performs.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EXAMPLE 1: Agent Introduction\n",
    "print(\"🤖 Starting Agent Introduction...\")\n",
    "introduction_query = \"Hello, who are you and what can you help me with?\"\n",
    "introduction_response = await query_agent(introduction_query)\n",
    "print_response(\"✅ AGENT INTRODUCTION\", introduction_response, max_length=1500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EXAMPLE 2: Basic Stock Analysis\n",
    "print(\"📊 Starting Apple Stock Analysis...\")\n",
    "stock_analysis_query = (\n",
    "    \"I'd like to analyze Apple stock (AAPL). Can you provide a comprehensive market analysis?\"\n",
    ")\n",
    "stock_analysis_response = await query_agent(stock_analysis_query)\n",
    "print_response(\"✅ APPLE STOCK ANALYSIS\", stock_analysis_response, max_length=2000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EXAMPLE 3: Complete Financial Advisory Process\n",
    "print(\"💼 Starting Comprehensive Microsoft Analysis...\")\n",
    "comprehensive_query = \"\"\"\n",
    "I'm interested in investing in Microsoft (MSFT). Here are my preferences:\n",
    "- Risk tolerance: Moderate\n",
    "- Investment period: Long-term (5+ years)\n",
    "- Goal: Build wealth for retirement\n",
    "\n",
    "Please provide a complete analysis including market data, trading strategies,\n",
    "execution plan, and risk assessment.\n",
    "\"\"\"\n",
    "\n",
    "comprehensive_response = await query_agent(comprehensive_query.strip())\n",
    "print_response(\"✅ COMPREHENSIVE MICROSOFT ANALYSIS\", comprehensive_response, max_length=3000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# EXAMPLE 4: Interactive Session\n",
    "print(\"🔄 Starting Interactive Tesla Analysis...\")\n",
    "\n",
    "# Step 1: Start with ticker\n",
    "step1_query = \"I want to analyze Tesla (TSLA)\"\n",
    "step1_response = await query_agent(step1_query)\n",
    "print_response(\"✅ STEP 1 - TESLA TICKER REQUEST\", step1_response, max_length=1000)\n",
    "\n",
    "# Step 2: Provide preferences\n",
    "step2_query = \"My risk attitude is aggressive and my investment period is medium-term (2-3 years)\"\n",
    "step2_response = await query_agent(step2_query)\n",
    "print_response(\"✅ STEP 2 - RISK AND TIMELINE PREFERENCES\", step2_response, max_length=1500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 🎯 CUSTOM QUERY INTERFACE - Modify and Run!\n",
    "# ✏️ Change the query below to ask your own questions\n",
    "\n",
    "custom_query = \"\"\"\n",
    "I'm a beginner investor with $10,000 to invest. I'm 25 years old and want to start building\n",
    "wealth for the long term. I have a moderate risk tolerance. What would you recommend for\n",
    "getting started with stock investing?\n",
    "\"\"\"\n",
    "\n",
    "print(\"🎯 Running your custom query...\")\n",
    "custom_response = await query_agent(custom_query.strip())\n",
    "print_response(\"✅ CUSTOM QUERY RESPONSE\", custom_response, max_length=2000)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
